package http

import (
	"bufio"
	"fmt"
	"io"
	"log"
	"os"
	"path"
	"strconv"
	"strings"

	"github.com/gin-gonic/gin"
	"github.com/toolkits/pkg/file"

	"github.com/didi/nightingale/src/modules/agent/config"
	"github.com/didi/nightingale/src/modules/agent/timer"
)

func output(idstr string, typ string) (string, error) {
	fp := path.Join(config.Config.Job.MetaDir, idstr, typ)
	if file.IsExist(fp) {
		return file.ToString(fp)
	}

	id, err := strconv.ParseInt(idstr, 10, 64)
	if err != nil {
		return "", err
	}

	t, has := timer.Locals.GetTask(id)
	if !has {
		return "", nil
	}

	if typ == "stdout" {
		return string(t.GetStdout()), nil
	}

	return string(t.GetStderr()), nil
}

func outputMd5diffContent(id string, fileName string) (string, error) {
	currentPath, _ := os.Getwd()
	fp := path.Join(currentPath, "env", fmt.Sprintf("service_%v", id), fileName)
	if file.IsExist(fp) {
		return ReadFileByLine(fp, 100)
	}
	return "", nil
}

func outputMd5diffFile(id string, fileName string) (string, error) {
	currentPath, _ := os.Getwd()
	fp := path.Join(currentPath, "env", fmt.Sprintf("service_%v", id), fileName)
	if file.IsExist(fp) {
		return file.ToString(fp)
	}
	return "", nil
}

func stdoutTxt(c *gin.Context) {
	content, err := output(urlParamStr(c, "id"), "stdout")
	if err != nil {
		log.Println("[E]", err)
		c.AbortWithError(500, fmt.Errorf("read stdout fail: %v", err))
		return
	}

	c.String(200, content)
}

func stdoutJSON(c *gin.Context) {
	content, err := output(urlParamStr(c, "id"), "stdout")
	renderData(c, content, err)
}

func stderrTxt(c *gin.Context) {
	content, err := output(urlParamStr(c, "id"), "stderr")
	if err != nil {
		log.Println("[E]", err)
		c.AbortWithError(500, fmt.Errorf("read stderr fail: %v", err))
		return
	}

	c.String(200, content)
}

func stderrJSON(c *gin.Context) {
	content, err := output(urlParamStr(c, "id"), "stderr")
	renderData(c, content, err)
}

func getMd5diffFile(c *gin.Context) {
	content, err := outputMd5diffFile(urlParamStr(c, "id"), "path.diff")
	renderData(c, content, err)
}

func getMd5diffContent(c *gin.Context) {
	content, err := outputMd5diffContent(urlParamStr(c, "id"), "path.diff")
	renderData(c, content, err)
}

func ReadFileByLine(path string, num int) (string, error) {
	fileHandler, err := os.OpenFile(path, os.O_RDONLY, 0666)
	if err != nil {
		return "", err
	}
	defer fileHandler.Close()

	reader := bufio.NewReader(fileHandler)
	var results []string
	flag := true
	for i := 0; i < num; i++ {
		line, _, err := reader.ReadLine()
		if err == io.EOF {
			if i < num {
				flag = false
			}
			break
		}
		results = append(results, string(line))
	}
	if flag {
		results = append(results, "更多内容请下载文件查看......")
	}
	return strings.Join(results, "\n"), nil
}
